package com.lyz.moil.core.security;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.hibernate.Query;
import org.hibernate.Session;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.stereotype.Repository;
import org.springframework.util.AntPathMatcher;

import com.lyz.moil.core.security.entity.Resources;
import com.lyz.moil.core.security.entity.Roles;
import com.lyz.moil.core.security.service.UserService;

/**
 * @description 资源源数据定义，将所有的资源和权限对应关系建立起来，即定义某一资源可以被哪些角色访问
 */
@Repository("securityMetadataSource")
public class MySecurityMetadataSource implements FilterInvocationSecurityMetadataSource {

	private UserService userService;
	/* 保存资源和权限的对应关系 key-资源url value-权限 */
	private Map<String, Collection<ConfigAttribute>> resourceMap = null;
	private AntPathMatcher urlMatcher = new AntPathMatcher();

	@Autowired
	public MySecurityMetadataSource(UserService userService) {
		this.userService = userService;
		try {
			loadResourcesDefine();
		} catch (Exception e) {
			System.out.println(e.getMessage());
		}
	}

	@Override
	public Collection<ConfigAttribute> getAllConfigAttributes() {
		return null;
	}

	public void loadResourcesDefine() {
		resourceMap = new HashMap<String, Collection<ConfigAttribute>>();
		// Collection<ConfigAttribute> configAttributes1 = new ArrayList<ConfigAttribute>() ;
		// ConfigAttribute configAttribute1 = new SecurityConfig("ROLE_ADMIN");
		// configAttributes1.add(configAttribute1);
		// resourceMap.put("/leftmenu.action", configAttributes1);

		Session session = userService.getBaseDao().getNewSession();
		session.beginTransaction();
		Query query = session.createQuery("from Roles");
		@SuppressWarnings("unchecked")
		List<Roles> roles = query.list();
		if (roles != null) {
			for (Roles role : roles) {
				Set<Resources> resources = role.getResources();
				for (Resources resource : resources) {
					Collection<ConfigAttribute> configAttributes = null;
					ConfigAttribute configAttribute = new SecurityConfig(role.getType());
					if (resourceMap.containsKey(resource.getUrl())) {
						configAttributes = resourceMap.get(resource.getUrl());
						configAttributes.add(configAttribute);
					} else {
						configAttributes = new ArrayList<ConfigAttribute>();
						configAttributes.add(configAttribute);
						resourceMap.put(resource.getUrl(), configAttributes);
					}
				}
			}
		}
		session.close();
	}

	/*
	 * 根据请求的资源地址，获取它所拥有的权限
	 */
	@Override
	public Collection<ConfigAttribute> getAttributes(Object obj) throws IllegalArgumentException {
		// 获取请求的url地址
		String url = ((FilterInvocation) obj).getRequestUrl();
		Iterator<String> it = resourceMap.keySet().iterator();
		while (it.hasNext()) {
			String _url = it.next();
			if (_url.indexOf("?") != -1) {
				_url = _url.substring(0, _url.indexOf("?"));
			}
			if (urlMatcher.match(url, _url))
				return resourceMap.get(_url);
		}
		return null;
	}

	@Override
	public boolean supports(Class<?> arg0) {
		return true;
	}

}